using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.IdentityModel.Tokens;
using mvcincode.Auth.Handler;
using mvcincode.Auth.Requirement;
using mvcincode.Models;

namespace mvcincode.Extensions;

public static class IServiceCollectionExtensions
{
    public static IServiceCollection AddMyServices(this IServiceCollection services)
    {
        // 默认Cookie认证
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie("Cookies", options =>
            {
                options.Cookie.HttpOnly = true;
                options.SlidingExpiration = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
                // options.LoginPath = new PathString("/Account/Login");
                // options.AccessDeniedPath = new PathString("/Account/Login");
            });

        // Jwt认证
        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,//是否验证Audience
                    ValidateLifetime = true,//是否验证失效时间
                    ClockSkew = TimeSpan.FromSeconds(30),
                    ValidateIssuerSigningKey = true,//是否验证SecurityKey
                    ValidAudience = JwtConstant.AUDIENCE,//Audience
                    ValidIssuer = JwtConstant.ISSUER,//Issuer，这两项和前面签发jwt的设置一致
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtConstant.SECURITY_KEY))
                };
            });

        // services.ConfigureApplicationCookie(options =>
        // {
        //     // Cookie settings
        //     options.Cookie.HttpOnly = true;
        //     options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        //     options.LoginPath = "/Identity/Account/Login";
        //     options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        //     options.SlidingExpiration = true;
        // });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("admin", config =>
            {
                config.RequireClaim(ClaimTypes.Name, "Alan");
                config.Requirements.Add(new Show404Requirement());
            });

            options.AddPolicy("BadgeEntry", policy =>
                policy.RequireAssertion(context => context.User.HasClaim(c =>
                    (c.Type == "BadgeId" || c.Type == "TemporaryBadgeId")
                        && c.Issuer == "https://microsoftsecurity")));

            // 基于资源的授权策略
            options.AddPolicy("DocumentPolicy", policy =>
                policy.Requirements.Add(new SameAuthorRequirement()));

            // 1.自定义授权策略提供程序:添加自定义requirement
            // options.AddPolicy("AtLeast21", policy =>
            // {
            //     policy.Requirements.Add(new MinimumAgeRequirement(20));
            // });

        });

        // 2.自定义授权策略提供程序:添加授权策略处理程序
        // services.AddSingleton<IAuthorizationHandler, MinimumAgeHandler>();


        services.AddSingleton<IAuthorizationHandler, SameAuthorHandler>();

        // 注册授权处理程序,一个Requirement必然对应一个Handler,否则验证用不成功
        services.AddSingleton<IAuthorizationHandler, Show404Handler>();
        // 注册授权中间件结果处理器
        services.AddSingleton<IAuthorizationMiddlewareResultHandler, MyAuthorizationMiddlewareResultHandler>();

        return services;
    }
}